package com.czone.myfacebook;

import java.util.ArrayList;
import java.util.HashMap;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.os.Bundle;
import android.support.v4.app.Fragment;
import android.view.View;
import android.widget.ImageView;

import com.czone.myfacebook.MainActivity.MainCallBack;
import com.facebook.FacebookRequestError;
import com.facebook.Request;
import com.facebook.Response;
import com.facebook.Session;
import com.facebook.model.GraphObject;

public class FaceBookDataManager {
    public final static String TAG = "FaceBookDataManager";

    //
    // FACE BOOK DATA MANAGE
    //
    private ArrayList<FaceBookData> mFeedDataList = new ArrayList<FaceBookData>();
    private HashMap<String, ProfileImageData> mProfileImageHash = new HashMap<String, ProfileImageData>();
    private FaceBookPageManager mFaceBookPageManager = new FaceBookPageManager();
    private FeedViewFragment mFeedViewFragment;

    //
    // MAINACTIVITY's fragments FOR CONNECTING
    //
    private Fragment[] mFragments;

    //
    // LIST LOCKING
    //
    private boolean mLockListView = false;

    //
    // LOADING BAR
    //
    private LoadingView mLoadingView;

    //
    // THREAD VALUE
    //
    private Thread mThread;
    private boolean mRequestDoing = false;
    private MainCallBack mMainCallBack;

    //
    // SINGLETON
    //
    // private static final FaceBookDataManager instance = new
    // FaceBookDataManager();

    // private FaceBookDataManager() {
    //
    // }

    // public static FaceBookDataManager getInstance() {
    // return instance;
    // }

    // public void setValues(Fragment[] fragments, LoadingView loadingview,
    // MainCallBack maincallback) {
    // mFragments = fragments;
    // mLoadingView = loadingview;
    // mMainCallBack = maincallback;
    // }

    public FaceBookDataManager(Fragment[] fragments, LoadingView loadingview, MainCallBack maincallback) {
        mFragments = fragments;
        mLoadingView = loadingview;
        mMainCallBack = maincallback;

        mFeedViewFragment = ((FeedViewFragment) mFragments[Define.FEEDVIEW]);
    }

    public FaceBookDataManager getInstance() {
        return this;
    }

    public ArrayList<FaceBookData> getFeedDataList() {
        return mFeedDataList;
    }

    public HashMap<String, ProfileImageData> getProfileData() {
        return mProfileImageHash;
    }

    private boolean getLockRequest() {
        return mRequestDoing;
    }

    public FaceBookDataManager getFaceBookDataManagerInstance() {
        return this;
    }

    private void lockRequest(boolean requestdoing) {
        mRequestDoing = requestdoing;
    }

    /**
     * request Feed Data
     * 
     * @param _pageNumber
     */
    private void sendRequestFeedData(int _pageNumber) {
        CLog.i(TAG, "sendRequestFeedData() E");

        // request filed
        Bundle params = getBundleforRequest();

        // request data
        new Request(Session.getActiveSession(), "me/home", params, null, new Request.Callback() {
            public void onCompleted(Response response) {
                GraphObject graphObject = response.getGraphObject();
                FacebookRequestError error = response.getError();

                if (graphObject != null) {
                    getDataGraphObject(graphObject, false);
                }
            }
        }).executeAndWait();
        CLog.i(TAG, "sendRequestFeedData() X");
    }

    /**
     * parsing graphObject Data
     * 
     * @param graphObject
     * @param addFeedData
     */
    private void getDataGraphObject(GraphObject graphObject, boolean addFeedData) {
        CLog.i(TAG, "getDataGraphObject E");

        if (null == graphObject)
            return;

        // parsing me/feed data
        if (graphObject.getProperty("data") != null) {
            JSONArray dataObjectArray = (JSONArray) graphObject.getProperty("data");

            try {
                CLog.d(TAG, "limit = " + dataObjectArray.length());

                int length = dataObjectArray.length();
                JSONObject dataObject;
                for (int i = 0; i < length; i++) {
                    dataObject = dataObjectArray.getJSONObject(i);
                    setFeedData(dataObject);
                }
            } catch (JSONException e) {
                CLog.e(TAG, "exeption = " + e);
            }
        } else {
            CLog.e(TAG, "getDataGraphObject data null....");
            if (mFeedViewFragment != null) {
                mFeedViewFragment.setFooterViewState(false);
            }

            return;
        }

        // parsing paging data
        if (graphObject.getProperty("paging") != null && mFaceBookPageManager != null) {
            CLog.d(TAG, "get paging");
            JSONObject dataObject = (JSONObject) graphObject.getProperty("paging");
            try {
                CLog.d(TAG, "pageing previous = " + dataObject.getString("previous"));
                CLog.d(TAG, "pageing next = " + dataObject.getString("next"));

                mFaceBookPageManager.setNext(dataObject.getString("next"));
                mFaceBookPageManager.setPrevious(dataObject.getString("previous"));

                CLog.d(TAG, "mFaceBookPageManager previous = " + mFaceBookPageManager.getPrevious());
                CLog.d(TAG, "mFaceBookPageManager next = " + mFaceBookPageManager.getNext());
            } catch (JSONException e) {
                e.printStackTrace();
            }
        } else {
            CLog.e(TAG, "getDataGraphObject paging null....");
            if (mFeedViewFragment != null) {
                mFeedViewFragment.setFooterViewState(false);
            }
        }
    }

    public void doRequestPage(final int requestpage) {
        mThread = new Thread() {
            public void run() {
                lockListView(true);
                sendRequestPage(requestpage);

                if (mFeedViewFragment != null)
                    mFeedViewFragment.setNewsfeedData(getInstance(), mMainCallBack);

                lockListView(false);
                mThread = null;
            }
        };
        mThread.start();
    }

    public void doRequestProfileImage(final ImageView v, final String requestID) {
        CLog.d(TAG, "doRequestProfileImage E");
        new Thread() {
            public void run() {
                sendRequsetProfileImage(v, requestID);
            }
        }.start();
    }

    /**
     * 
     * @param nextorprevious
     *            Define.REQUEST_NEXT_PAGE = 0; Define.REQUEST_PREVIOUS_PAGE =
     *            1;
     * @return
     */
    private void sendRequestPage(final int requestpage) {
        CLog.i(TAG, "requestPage = " + (requestpage == Define.REQUEST_NEXT_PAGE ? "NEXT" : "PREVIOUS"));

        if (mFeedViewFragment != null) {
            mFeedViewFragment.setFooterViewState(true);
        }

        // request check
        if (Define.REQUEST_NEXT_PAGE == requestpage && mFaceBookPageManager.getNext() == null || Define.REQUEST_NEXT_PAGE == requestpage && mFaceBookPageManager.getPrevious() == null) {
            if (mFeedViewFragment != null) {
                mFeedViewFragment.setFooterViewState(false);
            }
            return;
        }

        // request params setting
        Bundle params = getBundleforRequest();
        if (null != params) {
            if (Define.REQUEST_NEXT_PAGE == requestpage)
                params.putString("until", mFaceBookPageManager.getNext());
            else
                params.putString("since", mFaceBookPageManager.getPrevious());
        }

        CLog.i(TAG, "params String = " + params.getString("until") + ", " + params.getString("since"));

        // request data
        new Request(Session.getActiveSession(), "me/home", params, null, new Request.Callback() {
            public void onCompleted(Response response) {
                GraphObject graphObject = response.getGraphObject();
                FacebookRequestError error = response.getError();
                if (graphObject != null) {
                    getDataGraphObject(graphObject, Define.REQUEST_NEXT_PAGE == requestpage ? true : false);
                }
            }
        }).executeAndWait();
    }

    private Bundle getBundleforRequest() {
        // request filed
        Bundle params = new Bundle();
        params.putString("fields", Define.INDEX_ID + "," + Define.INDEX_FROM + "," + Define.INDEX_MESSAGE + "," + Define.INDEX_PICTURE + "," + Define.INDEX_DATE + "," + Define.INDEX_TYPE + ","
                + Define.INDEX_NAME + "," + Define.INDEX_STORY);
        params.putString("limit", "" + Define.INDEX_REQUEST_FEED_COUNT);
        params.putString("locale", "ko_KR");

        return params;
    }

    /**
     * Set Feed Data
     * 
     * @param dataObject
     */
    private void setFeedData(JSONObject dataObject) {
        CLog.d(TAG, "feedlowdata = " + (dataObject != null ? dataObject.toString() : "null"));

        FaceBookData feedData = new FaceBookData();

        String[] feedStringList = { Define.INDEX_FROM, Define.INDEX_ID, Define.INDEX_MESSAGE, Define.INDEX_PICTURE, Define.INDEX_DATE, Define.INDEX_TYPE, Define.INDEX_STORY, Define.INDEX_NAME };

        for (int i = 0; i < Define.INDEX_SIZE; i++) {
            try {
                String strObject = dataObject.getString(feedStringList[i]);
                feedData.setObject(feedStringList[i], strObject);
            } catch (JSONException e) {
                CLog.i(TAG, "setError[" + feedStringList[i] + "] e = " + e);
            }
        }

        if (null != mFeedDataList) {
            CLog.d(TAG, "feedData input = " + feedData.toString());
            mFeedDataList.add(feedData);

            // request profile image
            // if (null != mProfileImageHash &&
            // !mProfileImageHash.containsKey(feedData.getObject(Define.INDEX_FROM_ID)))
            // {
            // sendRequsetProfileImage(null,
            // feedData.getObject(Define.INDEX_FROM_ID));
            // }
        }
    }

    private void sendRequsetProfileImage(final ImageView iv, final String requestId) {
        CLog.i(TAG, "sendRequsetProfileImage E, " + requestId);

        if (null == requestId)
            return;

        Bundle params = new Bundle();
        params.putString("fields", "picture");

        new Request(Session.getActiveSession(), requestId, params, null, new Request.Callback() {
            public void onCompleted(Response response) {
                GraphObject graphObject = response.getGraphObject();
                FacebookRequestError error = response.getError();

                if (graphObject != null && mProfileImageHash != null) {
                    if (graphObject.getProperty("picture") != null) {
                        JSONObject dataObject = (JSONObject) graphObject.getProperty("picture");
                        try {
                            JSONObject profile = new JSONObject(dataObject.getString("data"));
                            boolean bContain = mProfileImageHash.containsKey(requestId);
                            ProfileImageData pID = null;
                            if (!bContain) {
                                CLog.d(TAG, "profileImageHash E");
                                pID = new ProfileImageData();
                                pID.setURL(profile.getString("url"));
                                mProfileImageHash.put(requestId, pID);
                            } else {
                                pID = mProfileImageHash.get(requestId);
                            }

                            if (pID != null)
                                new DownloadImageTask(iv, pID).execute(pID.getURL());

                        } catch (JSONException e) {
                        }
                        CLog.d(TAG, "dataObject = " + dataObject.toString());
                    }
                }
            }
        }).executeAndWait();

        CLog.i(TAG, "sendRequsetProfileImage X, " + requestId);
    }

    public void doRequestFeedData() {
        CLog.i(TAG, "doRequestFeedData Start");

        // Loading Data
        mThread = new Thread() {
            public void run() {
                if (getLockListView()) {
                    CLog.d(TAG, "doRequestFeedData() :: getLockListView() is true");
                    return;
                }

                lockListView(true);
                mLoadingView.show();
                sendRequestFeedData(0);

                if (mFeedViewFragment != null)
                    mFeedViewFragment.setNewsfeedData(getInstance(), mMainCallBack);

                CLog.d(TAG, "data request completed..");
                mLoadingView.hide();

                // call main callback
                if (mMainCallBack != null)
                    mMainCallBack.onCompleteRequest();

                lockListView(false);

                mThread = null;
            }
        };
        mThread.start();
    }

    public void lockListView(boolean status) {
        CLog.d(TAG, "lockListView() :: mLockListView = " + mLockListView + " status = " + status);
        mLockListView = status;
    }

    public boolean getLockListView() {
        return mLockListView;
    }

    public void onDestroy() {
        if (mThread != null) {
            mThread.interrupt();
            mThread = null;
        }

        if (mFeedDataList != null) {
            mFeedDataList.clear();
            mFeedDataList = null;
        }

        if (mProfileImageHash != null) {
            mProfileImageHash.clear();
            mProfileImageHash = null;
        }

        if (mFaceBookPageManager != null) {
            mFaceBookPageManager = null;
        }
    }
}
